#ifndef ARRAYLIST_H
#define ARRAYLIST_H

typedef struct _List List;

void listDebug(List* list);
List* newList();
List* createList(unsigned int tabsize);
void deleteList(List* list);

int listIsEmpty(List* list);
int listGetSize(List* list);

int listInsertAt(List* list,void* elm,unsigned int pos);
void listInsertFirst(List* list,void* elm);
void listInsertLast(List* list,void* elm);

void* listGetAt(List* list,unsigned int pos);
void* listGetFirst(List* list);
void* listGetLast(List* list);
void* listGetNext(List* list);
void* listGetPrev(List* list);

void* listRemAt(List* list, unsigned int pos);
void* listRemFirst(List* list);
void* listRemLast(List* list);
void* listRem(List* list,void* elm);

void* listReplaceAt(List* list,void* elm,unsigned int pos);
void* listReplace(List* list,void* elmNew,void* elmOld);
int listSwitch(List* list, unsigned int posA, unsigned int posB);
unsigned int listPosOf(List* list,void* elm);


/* Macros */
#define listForEach(elem,list) \
		for((elem) = listGetFirst((list)); \
			(elem) != NULL; \
			(elem) = listGetNext((list)))
#define listItForEach(elem,it) \
		for((elem) = listItGetCurrent((it)); \
			(elem) != NULL; \
			(elem) = listItGetNext((it)))

#define listItForEachInfinite(elem,it) \
		listItReset(it); \
		for((elem) = listItGetCurrent((it)); \
			(elem) != NULL; \
			(elem) = (((elem) = listItGetNext((it))) == NULL)?(elem):listItGetNext((it)))

#define LIST_INVALIDPOS (unsigned int)-1

/* Iterators */
typedef struct _ListIterator ListIterator;
void* newListIt();
void listItReset(ListIterator* it);
void* listItGetCurrent(ListIterator* it);
void* listItGetNext(ListIterator* it);
void* listItGetPrev(ListIterator* it);
void deleteListIt(ListIterator* it);

#endif
